import { ControlNode } from "./ControlNode";
import { NodeStatus } from "../NodeStatus";


/**
 * 尝试依次执行其所有子节点，并且每个子节点只有在成功执行后才会继续到下一个。
 * 如果任何一个子节点失败，整个序列失败。
 */
export class ReactiveSequence<T> extends ControlNode<T> {

    constructor(name: string,blackboard: T) {
        super(name,blackboard);
    }

    Tick(): NodeStatus {
        let success_count = 0;
        let running_count = 0;

        for (let index = 0; index < this.numChildren; index++) {
            const child_node = this.$children[index];
            const child_status = child_node.Evaluate();
            switch (child_status) {
                case NodeStatus.RUNNING:
                    running_count++;
                    this.HaltChildren(index + 1);
                    return NodeStatus.RUNNING;
                case NodeStatus.FAILURE:
                    this.HaltChildren();
                    return NodeStatus.FAILURE;
                case NodeStatus.SUCCESS:
                    success_count++;
                    break;
                case NodeStatus.IDLE:
                    throw new Error("ReactiveSequence: child node is idle");
                default:
                    throw new Error("ReactiveSequence: child node status is invalid");
            }
        }
        if (success_count == this.numChildren) {
            this.HaltChildren();
            return NodeStatus.SUCCESS;
        }
        return NodeStatus.RUNNING;
    }
}